#include <SDL/SDL.h>
#include <queue>
#include <vector>


#include "sentrada.h"
#include "svideo.h"
#include "sred.h"
#include "ssonido.h"
#include "evento.h"
#include "Personajes.h"
#include "Tecnologias.h"
#include "jugador.h"
#include "mapa.h"

using namespace std;


#ifndef _COORDENADA_
#define _COORDENADA_
 struct coordenada{
		unsigned int id;
		unsigned int x;
		unsigned int y;
		};

#endif


#ifndef _C_NUCLEO_
#define _C_NUCLEO_
/*
class c_sentrada;
class c_svideo;
class c_sred;
*/
class personaje;
class tecnologias;
class jugador;
class c_ssonido;

class c_nucleo
{
 private:
  queue<c_evento> eventos;
  int mousex,mousey;
  int tiempo;
  int ejercito,ejercito_enemigo;
  int nmapa;
  int comienza;
  int ptos_locales,puntos,puntos_cliente;
  bool servidor;
  c_sentrada * sentrada;
  c_svideo * svideo;
  c_sred * sred;
  c_ssonido * ssonido;
  vector<personaje> patriotas;
  vector<personaje> invasores;
  vector<tecnologias> tecs_pat,tecs_inv;
  vector<personaje> enemigos;
  vector<personaje> unidades_locales,unidades_remotas;
  vector<int> movimiento_ud_locales;
  vector<coordenada> posicion_ud_locales,posicion_ud_remotas;
  jugador j;
  bool ganador;
  int turno;
  c_mapa *lista_mapas;
  unsigned int num_mapas; //Numero total de mapas
  int mapa_actual; //Indice de la lista de mapas con el mapa en juego
 
    

 
 public:
  c_nucleo();
  ~c_nucleo();
  //Game loop
  void bucle();
  int mx() { return mousex; }
  int my() { return mousey; }
  void nuevo_evento(c_evento ev);
  //Asocia el subsistema de entrada
  void asociar_sentrada(c_sentrada * e) { sentrada = e; }
  //Asocia el subsistema de video
  void asociar_svideo(c_svideo * v) { svideo = v; }
  //Asocia el subsistema de red
  void asociar_sred(c_sred * r) { sred = r; }
  //Asocia el subsistema de sonido
  void asociar_ssonido(c_ssonido * s) { ssonido = s; }
  //Carga la información de las unidades de los patriotas
  void cargar_patriotas();
  //Carga la información de las unidades de los invasores
  void cargar_invasores();
  //Carga la información de las tecnologías
  void cargar_tecnologias();
  //Carga la información del jugador
  void cargar_jugador();
  //Actualiza las tecnologías con los logros conseguidos anteriormente
  void cargar_info_unidades();
  //Actualiza las tecnologías con los logros conseguidos anteriormente
  void cargar_info_tecnologias();
  //Devuelve todas las unidades disponibles
  vector<personaje> unidades_disponibles();
  //Devuelve todas las tecnologías disponibles
  vector<tecnologias> tecnologias_disponibles();
  //Efectúa la compra de la unidad num_unidad perteneciente al ejército 'ejercito'
  void comprar_unidad(int ejercito,int num_unidad);
  //Efectúa la compra de la tecnología num_tec perteneciente al ejército 'ejercito'
  void comprar_tecnologia(int ejercito,int num_tec);
  //Realiza el volcado de la memoria a los ficheros .save
  void volcado_memoria_a_ficheros();
  //Devuelve los índices de las tecnologías de nueva adquisición
  vector<int> nuevas_tecs(int ejercito);
  //Devuelve verdadero si la unidad 'p' está muerta
  bool muerto(personaje p);
  //Devuelve todas las tecnologías pertenecientes al ejército 'ejercito'
  vector<tecnologias> tecs(int ejercito);
  //Devuelve el nivel actual de la tecnología 'tecnologia' correspondiente al ejército 'ejército'
  int nivel_tec(int ejercito, int tecnologia);
  //Comprueba si la tecnología 'tec' se encuentra en el vector 'tecs_jug'
  int tec_en_vector(int tec,vector<tecnologias> tecs_jug);
  //Devuelve el índice de la tecnología 'tec' en el vector 'tecs_jug'
  int devuelve_tec(int tec,vector<tecnologias> tecs_jug);
  //Devuelve el dinero actual del jugador
  int dinero();
  //Elige el ejército local
  void elige_ejercito(int e);
  //Calcula la puntuación de la partida,la comunica al subsitema de red y selecciona las unidades que jugarán
  void recibe_puntuacion(int ptos_cliente);
  //Coloca las unidades locales en el mapa
  void coloca_unidades();
  //Envía al subsistema de red la posición de las unidades locales
  void envia_posicion_unidades();
  //Elige aleatoriamente que jugador comenzará el turno
  void elige_comienza_turno();
  //Envia al subsistema de red quien comienza el primer turno
  void envia_comienza_turno();
  //Devuelve el número de unidades del tipo 'num_unidad' del ejército 'ejercito'
  int num_unidades(int ejercito,int num_unidad);
  //Devuelve los índices de las unidades de nueva adquisición del ejército 'ejercito'
  vector<int> nuevas_uds(int ejercito);
  //Indica si la unidad con id 'ud' se encuentra en el vector 'uds_jug'(personajes)
  int ud_en_vector(int ud,vector<personaje> uds_jug);
  //Devuelve la unidad con id 'ud' del vector uds_jug
  int devuelve_ud(int ud,vector<personaje> uds_jug);
  //Indica si la unidad con id 'ud' se encuentra en el vector 'res' (enteros)
  bool esta_en_res(int ud,vector<int> res);
  //Devuelve todas las unidades del ejército que se le pasa como parámetro
  vector<personaje> unidades(int ejercito);
  //Recibe la posicion de las unidades remotas
  void recibe_posicion_remotas(int unidad,int x,int y);
  //Recibe los puntos finales con los que se jugará el juego
  void recibe_ptos_finales(int ptos);
  //Recibe las unidades remotas
  void recibe_remotas(int unidad,int vida,int blindaje);
  //Recibe el mapa elegido
  void recibe_mapa(int mapa);
  //Indica que se ha terminado de enviar las posiciones de las unidades
  void fin_pos_unidad();
  //Recibe el turno
  void recibe_turno(int tturno);
  //Indica que se ha terminado de enviar unidades
  void fin_unidad();
  //Inicializa la variable servidor indicando que es el cliente
  void cliente();
  //Incializa la variable servidor indicando que es el servidor
  void server();
  //Devuelve un vector con las unidades locales en juego
  vector<personaje> unidades_en_juego(){return unidades_locales;}
  //Devuelve un vector con la posicion de las unidades locales en juego
  vector<coordenada> pos_unidades_en_juego(){return posicion_ud_locales;}
  //Devuelve las unidades remotas en juego
  vector<personaje> unidades_en_juego_remotas(){return unidades_remotas;}
  //Devuelve un vector con las posiciones de las unidades remotas en juego
  vector<coordenada> pos_unidades_en_juego_remotas(){return posicion_ud_remotas;}
  //Devuelve el ejército
  int devuelve_ejercito(){return ejercito;}
  //Devuelve el ejercito enemigo
  int devuelve_ejercito_enemigo(){ return ejercito_enemigo; }
  //Recibe el ejercito enemigo
  void recibe_ejercito_enemigo(int ejer);
  //Inicializa el vector de movimiento de unidades cuando comienza el turno local
  void turno_pasa();
  //Actualiza los datos al final de la batalla
  void fin_batalla();
  //Devuelve el turno
  int devuelve_turno(){return turno;}
  //Guarda el mapa que se le pasa como parámetro
  void guardar_mapa(c_mapa mapa);
  //Devuelve el puntero al vector de mapas
  c_mapa* listar_mapas() {return lista_mapas; }
  //Devuelve el numero de mapas
  int num_maps() { return num_mapas; }
  //Devuelve el mapa cuyo md5 es el que se envía como parámetro
  c_mapa mapa(char * md5);
  //Borra el mapa cuyo md5 coincida con el que se envía como parámetro
  void borra_mapa(char * md5);
  //Carga los mapas
  void carga_mapas();
  //Elige un mapa aleatorio y envía el md5 por red
  void mapa_aleatorio();
  //Elige el mapa indicado por el entero que se le pasa como parámetro y lo envía por red
  void mapa_elegido(char * md5);
  //Comprueba si el mapa recibido esta entre los mapas propios y lo comunica por red
  void existe_mapa(char * md5);
  //Si recibe un 1,no hace nada.Si recibe un 0 manda un mensaje a la red indicando el mapa elegido para jugar
  void envia_mapa_elegido(int elec);
  //Guarda el mapa recibido en la lista y ademas lo elige para la batalla
  void fin_mapa(c_mapa m);
  //Realiza acciones relacionadas con el ataque
  int ataque_local(int idgl,int idgr);
  //Realiza el movimiento
  void movimiento_local(int idgl,int x,int y,int movimientorestante);
  //Procesa un ataque remoto
  void ataque_remoto(int idgl, int dano);
  //Procesa un movimiento remoto
  void movimiento_remoto(int idgr,int x, int y);
  //Cambia la variable turno y manda un mensaje por red para pasar el turno
  void termina_turno();
  //devuelve el valor absoluto de n
  int absolut(int n);
  //Devuelve la posicion del vector de coordenadas donde se encuentra la unidad con id general 'idg'
  int pos_id(unsigned int idg,vector<coordenada> locales);
  //Devuelve la vida de una unidad
  int vida(unsigned int idg,unsigned int ejercito);
};

#endif
